﻿using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using PlanningGIS.Framework;
using ESRI.ArcGIS.Controls;
using PlanningGIS.Framework.Controls;
using System.Runtime.InteropServices;
using PlanningGIS.Win.Controls;
using PlanningGIS.ArcGIS;
using PlanningGIS.Report;
using PlanningGIS.Framework.Rule;
using System.Collections.Generic;

namespace PlanningGIS.Statistics
{
    /// <summary>
    /// 绿化率统计
    /// </summary>
    internal class VegetableStatButton : BaseDrawPolygonTool
    {
        IApplication m_Application = null;
        private IElement m_pElement;
        private IFeatureLayer pFeatureLayer;
        private Hashtable m_pCodeAndNameHash = null;
        
        private int idxFcode;

        public VegetableStatButton()
        {
            base.m_caption = "绿化率统计";
            base.m_toolTip = base.m_caption;
            m_cursor = Cursors.Cross;
        }

        public override void OnCreate(object hook)
        {
            if (m_Application == null)
            {
                m_Application = hook as IApplication;
                base.OnCreate(hook);
            }
        }

        public override bool Enabled
        {
            get
            {
                return true;
            }
        }

        public override void OnClick()
        {
            try
            {
                IMapControl3 pMapControl = null;
                if ((m_Application as IFramework).IsMapCtrlactive)
                    pMapControl = (m_Application as IFramework).MapControl;
                else
                    return;

                if (pFeatureLayer == null)
                {
                    string featClsName = StatisticConfigHelper.StatisticConfig.植被绿化率统计.要素类名称;
                    if (!String.IsNullOrWhiteSpace(featClsName))
                    {
                        List<IFeatureLayer> allFeatLyrs = MapHelper.GetAllLayer<IFeatureLayer>(pMapControl.Map);
                        foreach (IFeatureLayer pFeatLyr in allFeatLyrs)
                        {
                            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
                            IDataset pDataset = pFeatCls as IDataset;
                            if (pDataset.Name == featClsName)
                            {
                                if (pFeatureLayer == null)
                                {
                                    pFeatureLayer = pFeatLyr;
                                }
                                else
                                {
                                    //如果有多个图层的要素类名称均满足配置要求，则弹出图层选择框由用户手动选择统计图层
                                    pFeatureLayer = null;
                                    break;
                                }
                            }
                        }
                    }

                    if (pFeatureLayer == null)
                    {
                        FrmLayerSelector frmLayerSelector = new FrmLayerSelector((m_Application as IFramework).Object, zjgisShapeType.Polygon);
                        if (frmLayerSelector.ShowDialog() == DialogResult.OK)
                        {
                            pFeatureLayer = frmLayerSelector.FeatureLayer;
                        }
                        else
                            return;
                    }

                    idxFcode = pFeatureLayer.FeatureClass.FindField(AppConfig.SystemConfig.常用字段.分类代码);
                    if (idxFcode == -1)
                    {
                        MsgHelper.ShowInfomationMsgbox("所选数据的字段不满足要求,无法进行统计!");
                        pFeatureLayer = null;
                        return;
                    }
                }

                FillHashtable();

                base.OnClick();
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox("绿化率统计统计失败：" + ex.Message);
                pFeatureLayer = null;
            }
        }

        public override void OnDblClick()
        {
            try
            {
                base.OnDblClick();
                if (pFeatureLayer == null) return;
                if (m_geom == null || m_geom.IsEmpty) return;
                IPolygon pPolygon = m_geom as IPolygon;
                ITopologicalOperator2 pTopo = pPolygon as ITopologicalOperator2;
                pTopo.IsKnownSimple_2 = false;
                pTopo.Simplify();
                pTopo.IsKnownSimple_2 = true;
                pPolygon.Project(((IGeoDataset)pFeatureLayer.FeatureClass).SpatialReference);

                Application.DoEvents();
                ISpatialFilter pSF = new SpatialFilterClass();
                pSF.Geometry = pPolygon;
                pSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                IFeatureCursor pFeatureCursor = pFeatureLayer.Search(pSF, false);
                DataTable pTable = GetDatatableByFeatureclass();
                IFeature pFeature = pFeatureCursor.NextFeature();
                while (pFeature != null)
                {
                    AddDatarow(pTable, pFeature, pPolygon);
                    pFeature = pFeatureCursor.NextFeature();
                }
                if (pTable.Rows.Count == 0)
                {
                    MsgHelper.ShowInfomationMsgbox("尚未检索到植被面数据，请重试！");
                    if (m_pElement != null)
                    {
                        IGraphicsContainer pGeoContainer = (m_Application.Document as IMxDocument).ActiveView as IGraphicsContainer;
                        pGeoContainer.DeleteElement(m_pElement);
                        m_pElement = null;
                        (m_Application.Document as IMxDocument).ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
                    }
                    return;
                }

                IArea pArea = m_geom as IArea;
                double dblArea = Math.Abs(pArea.Area);
                // 
                if (m_geom.SpatialReference is IGeographicCoordinateSystem)
                {
                    ISpatialReference pSpatialReference = GeometryHelper.GetSpatialByX(pArea.Centroid.X);
                    IClone pClone = m_geom as IClone;
                    IGeometry pGeomClone = pClone.Clone() as IGeometry;
                    pGeomClone.Project(pSpatialReference);
                    pArea = pGeomClone as IArea;
                    dblArea = pArea.Area;
                }
                // 
                if (dblArea < 0.000001) return;
                FrmReport pReport = new FrmReport();
                pReport.DataSource = pTable;
                pReport.ParameterValue = dblArea;
                pReport.FullName = AppConfig.StartupPath + @"\Report\Statistic\绿化率统计报表.rpt";
                //pReport.ReportName = "绿化率统计报表.rpt";
                pReport.Text = "绿化率统计报表";
                pReport.ShowDialog();
                (m_Application.Document as IMxDocument).ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox("绿化率统计统计失败：" + ex.Message);
            }
        }

        private static DataTable GetDatatableByFeatureclass()
        {
            DataTable pTable = new DataTable();
            DataColumn pColumn = new DataColumn("OID");
            pColumn.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("FCODE");
            pColumn.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("NAME");
            pColumn.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("AREA");
            pColumn.DataType = Type.GetType("System.Double");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("INTERSECTAREA");
            pColumn.DataType = Type.GetType("System.Double");
            pColumn.DefaultValue = 0.00;
            pTable.Columns.Add(pColumn);

            return pTable;
        }

        private  void AddDatarow(DataTable pTable, IFeature pFeature, IGeometry pGeo)
        {
            if (pFeature == null || pTable == null) return;
            DataRow pRow = pTable.NewRow();
            pRow["OID"] = pFeature.OID.ToString();
            string fcode = pFeature.get_Value(idxFcode).ToString();
            string fname = fcode;
            if(m_pCodeAndNameHash.ContainsKey(fcode))
                fname = m_pCodeAndNameHash[fcode].ToString();

            pRow["FCODE"] = fcode;
            pRow["NAME"] = fname;

            IPolygon pPolygon = pFeature.ShapeCopy as IPolygon;
            IArea pArea = pPolygon as IArea;
            double dblArea = Math.Abs(pArea.Area);

            if (pPolygon.SpatialReference is IGeographicCoordinateSystem)
            {
                ISpatialReference pSpatialReference = GeometryHelper.GetSpatialByX(pArea.Centroid.X);
                IClone pClone = pPolygon as IClone;
                IGeometry pGeomClone = pClone.Clone() as IGeometry;
                pGeomClone.Project(pSpatialReference);
                pArea = pGeomClone as IArea;
                dblArea = pArea.Area;
            }

            pRow["AREA"] = dblArea;

            ITopologicalOperator pTopo = pGeo as ITopologicalOperator;
            IGeometry pIntersectGeo = null;
            try
            {
                pIntersectGeo = pTopo.Intersect(pPolygon, esriGeometryDimension.esriGeometry2Dimension);
            }
            catch (Exception ex)
            {
                pIntersectGeo = null;
            }
            if (pIntersectGeo == null || pIntersectGeo.IsEmpty) return;
            pArea = pIntersectGeo as IArea;
            dblArea = Math.Abs(pArea.Area);
            pRow["INTERSECTAREA"] = dblArea;

            pTable.Rows.Add(pRow);

        }

        private void FillHashtable()
        {
            m_pCodeAndNameHash = new Hashtable();
            string aliasName = StatisticConfigHelper.StatisticConfig.植被绿化率统计.要素类别名;
            DataImportRule dataImportRuleCur = RuleConfig.DefaultImportRule;
            if (dataImportRuleCur == null) return;
            foreach (DlgTargetFeatureClass featureClass in dataImportRuleCur.dlgTargetFeatureClasses)
            {
                if (featureClass.FeatureClassAliasName == aliasName)
                {
                    m_pCodeAndNameHash = new Hashtable();
                    foreach (FeatureCode code in featureClass.featureCodes)
                    {
                        m_pCodeAndNameHash.Add(code.FCODE, code.FNAME);
                    }
                }
            }
        }

        public override int Bitmap
        {
            get
            {
                string bitmapResourceName = "PlanningGIS.Statistics.Res." + this.GetType().Name + ".png";
                System.IO.Stream s = GetType().Assembly.GetManifestResourceStream(bitmapResourceName);
                if (s == null) return 0;
                return new Bitmap(s).GetHbitmap().ToInt32(); 
            }
        }

    }
}
